﻿namespace Summoner
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.Networking;

    public class LoadViaRequest : MonoBehaviour
    {
        private static LoadViaRequest _instance = null;
        
        IEnumerator Get(string url, Action<byte[]> callback)
        {
            using (UnityWebRequest www = UnityWebRequest.Get(url))
            {
                yield return www.Send();
                if (www.isError)
                {
                    Debug.Log(www.error);
                    if (callback != null) { callback(null); }
                }
                else
                {
                    // Show results as text
                    Debug.Log(www.downloadHandler.text);
                    // Or retrieve results as binary data
                    if (callback != null) { callback(www.downloadHandler.data); }
                }
            }
        }

        IEnumerator GetAssetBundle
            (string filepath, Action<AssetBundle> callback)
        {
            using (UnityWebRequest www = UnityWebRequest.GetAssetBundle(filepath))
            {
                yield return www.Send();
                if (www.isError)
                {
                    Debug.Log(www.error);
                    if (callback != null) { callback(null); }
                }
                else
                {
                    AssetBundle bundle = ((DownloadHandlerAssetBundle)www.downloadHandler).assetBundle;
                    if (callback != null) { callback(bundle); }
                }
            }
        }

        IEnumerator GetTexture(string filepath, Action<Texture> callback)
        {
            using (UnityWebRequest www = UnityWebRequest.GetTexture(filepath))
            {
                yield return www.Send();
                if (www.isError)
                {
                    Debug.Log(www.error);
                    if (callback != null) { callback(null); }
                }
                else
                {
                    Texture texture = ((DownloadHandlerTexture)www.downloadHandler).texture;
                    if (callback != null) { callback(texture); }
                }
            }
        }

        IEnumerator GetAudioClip(string filepath, AudioType audioType, Action<AudioClip> callback)
        {
            using (UnityWebRequest www = UnityWebRequest.GetAudioClip(filepath, audioType))
            {
                yield return www.Send();
                if (www.isError)
                {
                    Debug.Log(www.error);
                    if (callback != null) { callback(null); }
                }
                else
                {
                    AudioClip audioclip = ((DownloadHandlerAudioClip)www.downloadHandler).audioClip;
                    if (callback != null) { callback(audioclip); }
                }
            }
        }

        IEnumerator GetAssetBundleViaGetContent(string url, Action<AssetBundle> callback)
        {
            // AssetBundle
            using (UnityWebRequest request = UnityWebRequest.GetAssetBundle(url))
            {
                yield return request.Send();
                AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(request);
                if (callback != null) { callback(bundle); }
            }
        }

        IEnumerator GetTextureViaGetContent(string filepath, Action<Texture> callback)
        {
            using (UnityWebRequest www = UnityWebRequest.GetAssetBundle(filepath))
            {
                yield return www.Send();
                Texture2D texture = DownloadHandlerTexture.GetContent(www);
                if (callback != null) { callback(texture); }
            }
        }

        IEnumerator GetAudioClipViaGetContent(string url, AudioType audioType, Action<AudioClip> callback)
        {
            // Audio
            using (UnityWebRequest request = UnityWebRequest.GetAudioClip(url, audioType))
            {
                yield return request.Send();
                AudioClip audioclip = DownloadHandlerAudioClip.GetContent(request);
                if (callback != null) { callback(audioclip); }
            }
        }

        IEnumerator LoadFromWeb(string url)
        {
            UnityWebRequest wr = new UnityWebRequest(url);
            DownloadHandlerTexture texDl = new DownloadHandlerTexture(true);
            wr.downloadHandler = texDl;
            yield return wr.Send();
            if (!wr.isError)
            {
                Texture2D t = texDl.texture;
                Sprite s = Sprite.Create(t, new Rect(0, 0, t.width, t.height), Vector2.zero, 1f);
            }
        }

        IEnumerator DownloadWithCustomHanlder<T>(string url, T downloadHandler, Action<T> callback) where T : DownloadHandler
        {
            using (UnityWebRequest www = UnityWebRequest.Get(url))
            {
                www.downloadHandler = downloadHandler;
                yield return www.Send();
                if(www.isError)
                {
                    if (callback != null) { callback(null); }
                }
                else
                {
                    if (callback != null) { callback((T)www.downloadHandler); }
                }
            }
        }

        IEnumerator UploadViaPost(string url, WWWForm form, Action<bool> callback)
        {
            using (UnityWebRequest www = UnityWebRequest.Post(url, form))
            {
                yield return www.Send();
                if (www.isError)
                {
                    Debug.Log(www.error);
                    if (callback != null) { callback(false); }
                }
                else
                {
                    Debug.Log("Form upload complete!");
                    if (callback != null) { callback(true); }
                }
            }
        }

        IEnumerator UploadViaPut(string url, byte[] data, Action<bool> callback)
        {
            using (UnityWebRequest www = UnityWebRequest.Put(url, data))
            {
                yield return www.Send();
                if (www.isError)
                {
                    Debug.Log(www.error);
                    if (callback != null) { callback(false); }
                }
                else
                {
                    Debug.Log("Upload complete!");
                    if (callback != null) { callback(true); }
                }
            }
        }

        IEnumerator UploadForm(string filepath, List<IMultipartFormSection> formData, Action<bool> callback)
        {
            //formData.Add(new MultipartFormDataSection("field1=foo&field2=bar"));
            //formData.Add(new MultipartFormFileSection("my file data", "myfile.txt"));
            using (UnityWebRequest www = UnityWebRequest.Post(filepath, formData))
            {
                yield return www.Send();
                if (www.isError)
                {
                    Debug.Log(www.error);
                    if (callback != null) { callback(false); }
                }
                else
                {
                    Debug.Log("Form upload complete!");
                    if (callback != null) { callback(true); }
                }
            }
        }

        IEnumerator UploadBytes(string filepath, byte[] data, Action<bool> callback)
        {
            using (UnityWebRequest www = UnityWebRequest.Put(filepath, data))
            {
                yield return www.Send();
                if (www.isError)
                {
                    Debug.Log(www.error);
                    if (callback != null) { callback(false); }
                }
                else
                {
                    Debug.Log("Upload complete!");
                    if (callback != null) { callback(true); }
                }
            }
        }

        IEnumerator UploadWithCustomHandlerViaPost<T>(string url, WWWForm form, T uploadHandler, Action<bool> callback) where T : UploadHandler
        {
            using (UnityWebRequest www = UnityWebRequest.Post(url, form))
            {
                www.uploadHandler = uploadHandler;
                yield return www.Send();
                if (www.isError)
                {
                    Debug.Log(www.error);
                    if (callback != null) { callback(false); }
                }
                else
                {
                    Debug.Log("Form upload complete!");
                    if (callback != null) { callback(true); }
                }
            }
        }

        IEnumerator UploadWithCustomHandlerViaPut<T>(string url, byte[] data, T uploadHandler, Action<bool> callback) where T : UploadHandler
        {
            using (UnityWebRequest www = UnityWebRequest.Put(url, data))
            {
                www.uploadHandler = uploadHandler;
                yield return www.Send();
                if (www.isError)
                {
                    Debug.Log(www.error);
                    if (callback != null) { callback(false); }
                }
                else
                {
                    Debug.Log("Upload complete!");
                    if (callback != null) { callback(true); }
                }
            }
        }

        public static LoadViaRequest Instance
        {
            get
            {
                if (_instance == null) { _instance = FindObjectOfType<LoadViaRequest>(); }
                if (_instance == null) { _instance = new GameObject("LoadViaRequest").AddComponent<LoadViaRequest>(); }
                return _instance;
            }
        }
    }
}